using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using TAAlert.BackTest;
using TALoaders;

namespace TAAlert.Tests
{
    using NUnit.Framework;

    [TestFixture]
    class TestStrategyDetails
    {
        [SetUp]
        public void Init()
        {
            CachedDownloader.clearCache();
        }

        [Test]
        [Category("Calculation")]
        public void testVEMAgeneration()
        {
            string loaderName = Loader.Test.ToString();
            string ticker = "SRM";
            DateTime startDate = new DateTime(2010,04,30);
            DateTime endDate = new DateTime(2010,05,31);
            double tc = 0;
            int n1 = 4;
            int n2 = 8;
            double volT = 0.30;
            double tolerance = 0.0000001;
            
            QuoteType sigType = QuoteType.AvgHLC;
            StrategyDetail sDetail = new StrategyDetail(loaderName, ticker, startDate, endDate, tc, sigType);

            DataTable dTable = sDetail.generateVEMATable(n1, n2, volT);
            Assert.AreEqual(startDate, dTable.Rows[0][0], "DataTable: first date");
            Assert.AreEqual(endDate, dTable.Rows[31][0], "DataTable: last date");
            Assert.AreEqual(1042.48, dTable.Rows[1][1], "DataTable: open");
            Assert.AreEqual(1079.8736, dTable.Rows[2][2], "DataTable: high");
            Assert.AreEqual(1056.1517999999999d, dTable.Rows[3][3], "DataTable: low");
            Assert.AreEqual(1067.9, dTable.Rows[4][4], "DataTable: close");
            Assert.AreEqual(1039.3439333333333d, dTable.Rows[5][5], "DataTable: AvgHLC");
            Assert.AreEqual(100, dTable.Rows[5][6], "DataTable: volume");
            Assert.AreEqual(984.15477010210464d, dTable.Rows[30][7], "DataTable: EMA1");
            Assert.AreEqual(979.70321026990348d, dTable.Rows[30][8], "DataTable: EMA2");
            Assert.AreEqual(0.29615356082569327d, dTable.Rows[30][9], "DataTable: Vol");
            Assert.AreEqual(1, dTable.Rows[31][10], "DataTable: Pos");
            Assert.AreEqual(-169.53, (double)dTable.Rows[31][11], tolerance, "DataTable: Cumulative P/L");
            Assert.AreEqual(-185.69, (double)dTable.Rows[30][12], tolerance,  "DataTable: DrawDown");

            DataColumn col = dTable.Columns[10];
            List<int> pos = new List<int>(dTable.Rows.Count);
            for (int i = 0; i < dTable.Rows.Count; ++i)
                pos.Add((int)dTable.Rows[i][10]);
            List<int> posExp = new List<int>(new int[] { 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1 });
            Assert.AreEqual(posExp, pos, "Comparing position column");

            // Test SaveToExcel:
            string tmpFileName = "tmpVEMADataTable.csv";
            string referenceCacheFile = "..\\..\\Tests\\VEMADataTable.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName);
            File.Delete(tmpFileName);
        }

        [Test]
        [Category("Calculation")]
        public void testEMAgeneration()
        {
            string loaderName = Loader.Test.ToString();
            string ticker = "SRM";
            DateTime startDate = new DateTime(2010, 04, 30);
            DateTime endDate = new DateTime(2010, 05, 31);
            double tc = 0;
            int nEMA = 4;
            double tolerance = 0.00000001;

            QuoteType sigType = QuoteType.AvgHLC;
            StrategyDetail sDetail = new StrategyDetail(loaderName, ticker, startDate, endDate, tc, sigType);

            DataTable dTable = sDetail.generateEMATable(nEMA);
            Assert.AreEqual(-126.53, (double)dTable.Rows[31][9], tolerance, "Total PL");
            Assert.AreEqual(-126.53, (double)dTable.Rows[31][10], tolerance, "Last DrawDown");

            // Test SaveToExcel:
            string tmpFileName = "tmpEMADataTable.csv";
            string referenceCacheFile = "..\\..\\Tests\\EMADataTable.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName);
            File.Delete(tmpFileName);
        }

        [Test]
        [Category("Calculation")]
        public void testTwoEMAgeneration() 
        {
            string loaderName = Loader.Test.ToString();
            string ticker = "SRM";
            DateTime startDate = new DateTime(2010, 04, 30);
            DateTime endDate = new DateTime(2010, 05, 31);
            double tc = 0;
            int nShort = 5;
            int nLong = 10;
            double volT = double.PositiveInfinity;
            double tolerance = 0.000001;

            QuoteType sigType = QuoteType.AvgHLC;
            StrategyDetail sDetail = new StrategyDetail(loaderName, ticker, startDate, endDate, tc, sigType);

            DataTable dTable = sDetail.generateTwoEmaTable(nShort, nLong, volT);
            Assert.AreEqual(990.2873335327962d, dTable.Rows[31][7], "Last EMAShort");
            Assert.AreEqual(-23.85, (double)dTable.Rows[31][12], tolerance, "Last DrawDown");

            // Test SaveToExcel:
            string tmpFileName = "tmpTwoEMADataTable.csv";
            string referenceCacheFile = "..\\..\\Tests\\TwoEMADataTable.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName, "0: comparing " + tmpFileName + " with " + referenceCacheFile);
            File.Delete(tmpFileName);

            // Test TwoEma with volatility cut-out
            volT = 0.30;
            dTable = sDetail.generateTwoEmaTable(nShort, nLong, volT);
            Assert.AreEqual(-78.200, (double)dTable.Rows[10][12], tolerance, "1: MaxDrawDown");
            Assert.AreEqual(-8.33, (double)dTable.Rows[31][12], tolerance, "1: Last DrawDown");
            referenceCacheFile = "..\\..\\Tests\\TwoEMADataTable1.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName, "1: comparing " + tmpFileName + " with " + referenceCacheFile);
            File.Delete(tmpFileName);
        }

        [Test]
        [Category("Calculation")]
        public void testMACDgeneration()
        {
            string loaderName = Loader.Test.ToString();
            string ticker = "SRM";
            DateTime startDate = new DateTime(2010, 04, 30);
            DateTime endDate = new DateTime(2010, 05, 31);
            double tc = 0;
            int nShort = 12;
            int nLong = 26;
            int nFast = 9;

            QuoteType sigType = QuoteType.AdjClose;
            StrategyDetail sDetail = new StrategyDetail(loaderName, ticker, startDate, endDate, tc, sigType);

            DataTable dTable = sDetail.generateMACDTable(nShort, nLong, nFast);

            Assert.AreEqual(-40.01, Convert.ToDouble(dTable.Rows[30][11]), 0.0000001, "2010-05-20 DrawDown");

            // Test SaveToExcel:
            string tmpFileName = "tmpMACDDataTable.csv";
            string referenceCacheFile = "..\\..\\Tests\\MACDDataTable.csv";
            Utilities.saveDataTableToCSV(tmpFileName, dTable);
            FileAssert.AreEqual(referenceCacheFile, tmpFileName);
            File.Delete(tmpFileName);
        }

    }
}
